package com.zhixiang.core.web.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.AccessDeniedException;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.zhixiang.core.security.SecurityDataSource;

public class SecurityInterceptorFilter extends OncePerRequestFilter
{
  private HashMap<String, Set<String>> roleUrlsMap = null;
  private SecurityDataSource securityDataSource;

  public void setSecurityDataSource(SecurityDataSource paramSecurityDataSource)
  {
    this.securityDataSource = paramSecurityDataSource;
  }

  protected void doFilterInternal(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, FilterChain paramFilterChain)
    throws ServletException, IOException
  {
    String str = paramHttpServletRequest.getRequestURI();

    if (StringUtils.hasLength(paramHttpServletRequest.getContextPath()))
    {
      String s1 = paramHttpServletRequest.getContextPath();
      int i = str.indexOf(s1);
      if (i != -1) {
        str = str.substring(i + s1.length());
      }
    }
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    boolean flag = false;
    for (int j = 0; j < authentication.getAuthorities().length; j++)
    {
      if ("超级管理员".equals(authentication.getAuthorities()[j].getAuthority()))
//      if ("ROLE_ANONYMOUS".equals(authentication.getAuthorities()[j].getAuthority()))
      {
        flag = true;
        break;
      }
      if ("ROLE_PUBLIC".equals(authentication.getAuthorities()[j].getAuthority())) {
        flag = true;
      }
    }
    if ((!flag) && (!isUrlGrantedRight(str, authentication)))
    {
      if (this.logger.isDebugEnabled())
        this.logger.info("ungranted url:" + str);
      if (str.startsWith("/mobile/"))
      {
        paramHttpServletResponse.sendRedirect(paramHttpServletRequest.getContextPath() + "/mobile/login.jsp");
        return;
      }
      throw new AccessDeniedException("Access is denied! Url:" + str + " User:" + SecurityContextHolder.getContext().getAuthentication().getName());
    }
    if (this.logger.isDebugEnabled())
      this.logger.debug("pass the url:" + str);
    paramFilterChain.doFilter(paramHttpServletRequest, paramHttpServletResponse);
  }

  private boolean isUrlGrantedRight(String paramString, Authentication paramAuthentication)
  {
    for (GrantedAuthority localGrantedAuthority : paramAuthentication.getAuthorities())
    {
      Set<String>  localSet =this.roleUrlsMap.get(localGrantedAuthority.getAuthority());
      if ((localSet != null) && (localSet.contains(paramString)))
        return true;
    }
    return false;
//      return true;
  }

  public void loadDataSource()
  {
    this.roleUrlsMap = this.securityDataSource.getDataSource();
  }

  public void afterPropertiesSet()
    throws ServletException
  {
    loadDataSource();
//    if (this.roleUrlsMap == null)
//      throw new RuntimeException("没有进行设置系统的权限匹配数据源");
  }
}

